using System;
using System.Collections.Generic;
using System.Data;
using System.Xml;
using Microsoft.Health.Samples.PatientConnect.ContosoHealth.HealthVaultAdapter;

namespace Microsoft.Health.Samples.PatientConnect.ContosoHealth.HealthVaultAdapter
{
    /// <summary>
    /// Patient class provides properties and methods to add, update, delete
    /// and select patient records.
    /// </summary>
    public class Patient
    {
        private Guid _patientId = Guid.Empty;
        private string _medicalrecordnumber = String.Empty;
        private string _lastName = String.Empty;
        private string _firstName = String.Empty;
        private string _middleName = String.Empty;
        private int? _yearOfBirth = null;
        private string _gender = String.Empty;
        private string _city = String.Empty;
        private string _state = String.Empty;
        private string _country = String.Empty;
        private bool? _active = true;
        private bool? _registeredWithHealthVault = false;
        private Guid _personId = Guid.Empty;
        private Guid _recordId = Guid.Empty;
        private PatientDBHandler _patientDataSet = null;

        /// <summary>
        /// Patient's Xml file.
        /// </summary>
        private string _patientXml = String.Empty;

        /// <summary>
        /// Constructor for patient class.
        /// </summary>
        /// <param name="xmlFileName">Patient's xml file name.</param>
        public Patient(string xmlFileName)
        {
            _patientXml = xmlFileName;
            _patientDataSet = new PatientDBHandler(xmlFileName);
        }

        /// <summary>
        /// PatientId of the patient
        /// </summary>
        public Guid PatientId
        {
            get { return _patientId; }
            set { _patientId = value; }
        }

        /// <summary>
        /// Medical record number of the patient
        /// </summary>
        public string MedicalRecordNumber
        {
            get { return _medicalrecordnumber; }
            set { _medicalrecordnumber = value; }
        }

        /// <summary>
        /// Last name of the patient
        /// </summary>
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }

        /// <summary>
        /// First name of the patient
        /// </summary>
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        /// <summary>
        /// Middle name of the patient
        /// </summary>
        public string MiddleName
        {
            get { return _middleName; }
            set { _middleName = value; }
        }

        /// <summary>
        /// Year of brith for the patient
        /// </summary>
        public int? YearOfBirth
        {
            get { return _yearOfBirth; }
            set { _yearOfBirth = value; }
        }

        /// <summary>
        /// Gender of the patient
        /// </summary>
        public string Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }

        /// <summary>
        /// City of the patient
        /// </summary>
        public string City
        {
            get { return _city; }
            set { _city = value; }
        }

        /// <summary>
        /// State of the patient
        /// </summary>
        public string State
        {
            get { return _state; }
            set { _state = value; }
        }

        /// <summary>
        /// Country of the patient
        /// </summary>
        public string Country
        {
            get { return _country; }
            set { _country = value; }
        }

        /// <summary>
        /// Determines whether patient is Active
        /// </summary>
        public Boolean? Active
        {
            get { return _active; }
            set { _active = value; }
        }

        /// <summary>
        /// Determines whether patient is registered with HealthVault
        /// </summary>
        public Boolean? RegisteredWithHealthVault
        {
            get { return _registeredWithHealthVault; }
            set { _registeredWithHealthVault = value; }
        }

        /// <summary>
        /// PersonId of the patient in HealthVault
        /// </summary>
        public Guid PersonId
        {
            get { return _personId; }
            set { _personId = value; }
        }

        /// <summary>
        /// RecordId of the patient in HealthVault
        /// </summary>
        public Guid RecordId
        {
            get { return _recordId; }
            set { _recordId = value; }
        }
        /// <summary>
        /// Adds new patient in Patient's xml file.
        /// </summary>        
        public void AddPatient()
        {
            _patientDataSet.AddPatient(this.PatientId, this.MedicalRecordNumber, this.LastName, this.FirstName,
                                                     this.MiddleName, this.YearOfBirth, this.Gender, this.City, this.State, this.Country,
                                                     this.Active, this.RegisteredWithHealthVault, this.PersonId,
                                                     this.RecordId);
            _patientDataSet.Commit();
        }

        /// <summary>
        /// Updates record of the existing patient in Patient's xml file.
        /// </summary>        
        /// <param name="condition">Condition on which patient's records are to be updated.</param>
        /// <returns>Number of rows affected.</returns>
        public int UpdatePatient(string condition)
        {
            //PatientsDataSet.PatientRow[] patientRows = null;
            DataRow[] patientRows = null;
            int rowCount = 0;
            int rowsAffected = 0;

            patientRows = _patientDataSet.SelectPatient(condition);
            rowCount = patientRows.Length;

            for (int counter = 0; counter < rowCount; counter++)
            {
                if (!String.IsNullOrEmpty(this.FirstName))
                {
                    patientRows[counter]["FirstName"] = this.FirstName;
                }

                if (!String.IsNullOrEmpty(this.LastName))
                {
                    patientRows[counter]["LastName"] = this.LastName;
                }

                if (!String.IsNullOrEmpty(this.MiddleName))
                {
                    patientRows[counter]["MiddleName"] = this.MiddleName;
                }

                if (!String.IsNullOrEmpty(this.MedicalRecordNumber))
                {
                    patientRows[counter]["MedicalRecordNumber"] = this.MedicalRecordNumber;
                }

                if (this.YearOfBirth != null)
                {
                    patientRows[counter]["YearOfBirth"] = this.YearOfBirth;
                }

                if (!String.IsNullOrEmpty(this.Gender))
                {
                    patientRows[counter]["Gender"] = this.Gender;
                }

                if (!String.IsNullOrEmpty(this.City))
                {
                    patientRows[counter]["City"] = this.City;
                }

                if (!String.IsNullOrEmpty(this.State))
                {
                    patientRows[counter]["State"] = this.State;
                }

                if (!String.IsNullOrEmpty(this.Country))
                {
                    patientRows[counter]["Country"] = this.Country;
                }

                if (this.Active != null)
                {
                    patientRows[counter]["Active"] = this.Active;
                }

                if (this.RegisteredWithHealthVault != null)
                {
                    patientRows[counter]["RegisteredWithHealthVault"] = this.RegisteredWithHealthVault;
                }

                if (this.PersonId != Guid.Empty)
                {
                    patientRows[counter]["HV_Person_ID"] = this.PersonId;
                }

                if (this.RecordId != Guid.Empty)
                {
                    patientRows[counter]["HV_Record_ID"] = this.RecordId;
                }
            }

            if (rowCount != 0)
            {
                _patientDataSet.UpdatePatient(patientRows);
                _patientDataSet.Commit();

            }
            rowsAffected = patientRows.Length;
            return rowsAffected;
        }

        /// <summary>
        /// Selects the patient records
        /// </summary>
        /// <param name="condition">condition</param>
        /// <returns>List of patient</returns>
        public List<Patient> SelectPatientRecords(string condition)
        {
            DataRow[] patientRows = null;
            List<Patient> patientList = null;
            Patient patient;
            int rowCount = 0;

            patientRows = _patientDataSet.SelectPatient(condition);
            rowCount = patientRows.Length;
            patientList = new List<Patient>();

            for (int counter = 0; counter < rowCount; counter++)
            {
                patient = new Patient(_patientXml);
                patient.LastName = patientRows[counter]["LastName"].ToString();
                patient.FirstName = patientRows[counter]["FirstName"].ToString();
                patient.MiddleName = patientRows[counter]["MiddleName"].ToString();
                if (!string.IsNullOrEmpty(patientRows[counter]["YearOfBirth"].ToString()))
                {
                    patient.YearOfBirth = Convert.ToInt16(patientRows[counter]["YearOfBirth"].ToString());
                }
                patient.Gender = patientRows[counter]["Gender"].ToString();
                patient.Active = Convert.ToBoolean(patientRows[counter]["Active"]);
                patient.City = patientRows[counter]["City"].ToString();
                patient.State = patientRows[counter]["State"].ToString();
                patient.Country = patientRows[counter]["Country"].ToString();
                patient.MedicalRecordNumber = patientRows[counter]["MedicalRecordNumber"].ToString();
                patient.PatientId = new Guid(patientRows[counter]["id"].ToString());
                patient.PersonId = new Guid(patientRows[counter]["HV_Person_ID"].ToString());
                patient.RecordId = new Guid(patientRows[counter]["HV_Record_ID"].ToString());
                patient.RegisteredWithHealthVault = Convert.ToBoolean(patientRows[counter]["RegisteredWithHealthVault"].ToString());

                patientList.Add(patient);
            }
            return patientList;
        }
    }
}